namespace CLELCore.Assembly.CLELInstructions
{
	public static class LoadStoreUtilities
	{
		public static bool IsLoadConstant(CLELInstruction inst)
		{
			if(inst != null)
			{
				if(LoadStoreUtilities.IsLoadIntConstant(inst))
					return true;
				else if(LoadStoreUtilities.IsLoadLongConstant(inst))
					return true;
				else if(LoadStoreUtilities.IsLoadFloatConstant(inst))
					return true;
				else if(LoadStoreUtilities.IsLoadDoubleConstant(inst))
					return true;
			}
			return false;
		}
	
		public static bool IsLoadIntConstant(CLELInstruction inst)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDCI4M1)
					return true;
				else if(opcode == CLELOpcode.LDCI40)
					return true;
				else if(opcode == CLELOpcode.LDCI41)
					return true;
				else if(opcode == CLELOpcode.LDCI42)
					return true;
				else if(opcode == CLELOpcode.LDCI43)
					return true;
				else if(opcode == CLELOpcode.LDCI44)
					return true;
				else if(opcode == CLELOpcode.LDCI45)
					return true;
				else if(opcode == CLELOpcode.LDCI46)
					return true;
				else if(opcode == CLELOpcode.LDCI47)
					return true;
				else if(opcode == CLELOpcode.LDCI48)
					return true;
				else if(opcode == CLELOpcode.LDCI4S)
					return true;
				else if(opcode == CLELOpcode.LDCI4)
					return true;
			}
			return false;
		}

		public static bool IsLoadLongConstant(CLELInstruction inst)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDCI8)
					return true;
			}
			return false;
		}

		public static bool IsLoadFloatConstant(CLELInstruction inst)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDCR4)
					return true;
			}
			return false;
		}

		public static bool IsLoadDoubleConstant(CLELInstruction inst)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDCR8)
					return true;
			}
			return false;
		}
	
		public static bool GetLoadIntConstant(CLELInstruction inst,ref int num)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDCI4M1)
				{
					num = -1;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI40)
				{
					num = 0;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI41)
				{
					num = 1;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI42)
				{
					num = 2;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI43)
				{
					num = 3;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI44)
				{
					num = 4;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI45)
				{
					num = 5;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI46)
				{
					num = 6;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI47)
				{
					num = 7;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI48)
				{
					num = 8;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI4S)
				{
					Ldci4s ldci4s = (Ldci4s)inst;
					num = ldci4s.Constant;
					return true;
				}
				else if(opcode == CLELOpcode.LDCI4)
				{
					Ldci4 ldci4 = (Ldci4)inst;
					num = ldci4.Constant;
					return true;
				}
			}
			return false;
		}

		public static bool GetLoadLongConstant(CLELInstruction inst,ref long num)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDCI8)
				{
					Ldci8 ldci8 = (Ldci8)inst;
					num = ldci8.Constant;
					return true;
				}
			}
			return false;
		}

		public static bool GetLoadFloatConstant(CLELInstruction inst,ref float num)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDCR4)
				{
					Ldcr4 ldcr4 = (Ldcr4)inst;
					num = ldcr4.Constant;
					return true;
				}
			}
			return false;
		}
		
		public static bool GetLoadDoubleConstant(CLELInstruction inst,ref double num)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDCR8)
				{
					Ldcr8 ldcr8 = (Ldcr8)inst;
					num = ldcr8.Constant;
					return true;
				}
			}
			return false;
		}

		public static bool IsLoadLocalAddress(CLELInstruction inst)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDLOCAS)
					return true;
				else if(opcode == CLELOpcode.OBJECTMODEL)
				{
					ObjectModel om = (ObjectModel)inst;
					byte fun = om.Function;
					if(fun == CLELOpcode.LDLOCA)
						return true;
				}
			}
			return false;
		}

		public static bool GetLoadLocalAddressNum(CLELInstruction inst,ref int num)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDLOCAS)
				{
					Ldlocas ldlocas = (Ldlocas)inst;
					num = ldlocas.Local;
					return true;
				}
				else if(opcode == CLELOpcode.OBJECTMODEL)
				{
					ObjectModel om = (ObjectModel)inst;
					byte fun = om.Function;
					if(fun == CLELOpcode.LDLOCA)
					{
						Ldloca ldloca = (Ldloca)inst;
						num = ldloca.Local;
						return true;
					}
				}
			}
			return false;
		}

		public static bool GetLoadLocalNum(CLELInstruction inst,ref int num)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.LDLOC0)
				{
					num = 0;
					return true;
				}
				else if(opcode == CLELOpcode.LDLOC1)
				{
					num = 1;
					return true;
				}
				else if(opcode == CLELOpcode.LDLOC2)
				{
					num = 2;
					return true;
				}
				else if(opcode == CLELOpcode.LDLOC3)
				{
					num = 3;
					return true;
				}
				else if(opcode == CLELOpcode.LDLOCS)
				{
					Ldlocs ldlocs = (Ldlocs)inst;
					num = ldlocs.Local;
					return true;
				}
				else if(opcode == CLELOpcode.LDLOCAS)
				{
					Ldlocas ldlocas = (Ldlocas)inst;
					num = ldlocas.Local;
					return true;
				}
				else if(opcode == CLELOpcode.OBJECTMODEL)
				{
					ObjectModel om = (ObjectModel)inst;
					byte fun = om.Function;
					if(fun == CLELOpcode.LDLOC)
					{
						Ldloc ldloc = (Ldloc)om;
						num = ldloc.Local;
						return true;
					}
					else if(fun == CLELOpcode.LDLOCA)
					{
						Ldloca ldloca = (Ldloca)om;
						num = ldloca.Local;
						return true;
					}
				}
			}
			return false;
		}

		public static bool IsStoreLocal(CLELInstruction inst)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.STLOC0)
					return true;
				else if(opcode == CLELOpcode.STLOC1)
					return true;
				else if(opcode == CLELOpcode.STLOC2)
					return true;
				else if(opcode == CLELOpcode.STLOC3)
					return true;
				else if(opcode == CLELOpcode.STLOCS)
					return true;
				else if(opcode == CLELOpcode.OBJECTMODEL)
				{
					ObjectModel om = (ObjectModel)inst;
					byte fun = om.Function;
					if(fun == CLELOpcode.STLOC)
						return true;
				}
			}
			return false;
		}

		public static bool GetStoreLocalNum(CLELInstruction inst,ref int num)
		{
			if(inst != null)
			{
				byte opcode = inst.Opcode;
				if(opcode == CLELOpcode.STLOC0)
				{
					num = 0;
					return true;
				}
				else if(opcode == CLELOpcode.STLOC1)
				{
					num = 1;
					return true;
				}
				else if(opcode == CLELOpcode.STLOC2)
				{
					num = 2;
					return true;
				}
				else if(opcode == CLELOpcode.STLOC3)
				{
					num = 3;
					return true;
				}
				else if(opcode == CLELOpcode.STLOCS)
				{
					Stlocs stlocs = (Stlocs)inst;
					num = stlocs.Local;
					return true;
				}
				else if(opcode == CLELOpcode.OBJECTMODEL)
				{
					ObjectModel om = (ObjectModel)inst;
					byte fun = om.Function;
					if(fun == CLELOpcode.STLOC)
					{
						Stloc stloc = (Stloc)inst;
						num = stloc.Local;
						return true;
					}
				}
			}
			return false;
		}
	}
}
